/* * ApplicationInsights-Java * Copyright (c) Microsoft Corporation * All rights reserved. * * MIT License * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the ""Software""), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, and to permit * persons to whom the Software is furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package com.microsoft.applicationinsights.log4j.v2; import com.microsoft.applicationinsights.internal.common.LogTelemetryClientProxy; import com.microsoft.applicationinsights.internal.common.TelemetryClientProxy; import com.microsoft.applicationinsights.internal.logger.InternalLogger; import com.microsoft.applicationinsights.log4j.v2.internal.ApplicationInsightsLogEvent; import org.apache.logging.log4j.core.*; import org.apache.logging.log4j.core.appender.AbstractAppender; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.config.plugins.PluginAttribute; import org.apache.logging.log4j.core.config.plugins.PluginFactory; @Plugin(name="ApplicationInsightsAppender", category = "Core", elementType = "appender") public class ApplicationInsightsAppender extends AbstractAppender { //region Members private boolean isInitialized = false; private transient TelemetryClientProxy telemetryClientProxy; private static final long serialVersionUID = 1L; //endregion Members //region Ctor /** * Constructs new Application Insights appender. * @param name The appender name. * @param instrumentationKey The instrumentation key. */ protected ApplicationInsightsAppender(String name, String instrumentationKey) { super(name, null, null); try { telemetryClientProxy = new LogTelemetryClientProxy(instrumentationKey); this.isInitialized = true; } catch (Exception e) { // Appender failure must not fail the running application. this.isInitialized = false; InternalLogger.INSTANCE.error("Failed to initialize appender with exception: %s.", e.getMessage()); } } //endregion Ctor //region Public methods public LogTelemetryClientProxy getTelemetryClientProxy() { return (LogTelemetryClientProxy)this.telemetryClientProxy; } /** * Creates new appender with the given name and instrumentation key. * This method is being called on the application startup upon Log4j system initialization. * @param name The appender name. * @param instrumentationKey The instrumentation key. * @return New Application Insights appender. */ @PluginFactory public static ApplicationInsightsAppender createAppender( @PluginAttribute("name") String name, @PluginAttribute("instrumentationKey") String instrumentationKey) { return new ApplicationInsightsAppender(name, instrumentationKey); } /** * Logs a LogEvent using whatever logic this Appender wishes to use. It is typically recommended to use a * bridge pattern not only for the benefits from decoupling an Appender from its implementation, but it is also * handy for sharing resources which may require some form of locking. * * @param event The LogEvent. */ @Override public void append(LogEvent event) { if (!this.isStarted() || !this.isInitialized) { // TODO: trace not started or not initialized. return; } try { ApplicationInsightsLogEvent aiEvent = new ApplicationInsightsLogEvent(event); this.telemetryClientProxy.sendEvent(aiEvent); } catch (Exception e) { // Appender failure must not fail the running application. // TODO: Assert.Debug/warning on exception? } } /** * This method is being called on object initialization. */ @Override public void start() { super.start(); } //endregion Public methods }